import sys

from PySide6.QtCore import Qt, QTimer
from PySide6.QtWidgets import QApplication, QMainWindow, QProgressDialog, QPushButton, QVBoxLayout, QWidget

class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.progress = None
        self.setWindowTitle("QProgressDialog Demo")

        self.minimum_value = 0
        self.maximum_value = 100
        self.current_value = 0

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.progress_dialog_update)
        self.timer.setTimerType(Qt.TimerType.PreciseTimer)
        self.timer.setInterval(20)  # 每20毫秒触发一次

        self.begin_button = QPushButton("开始运行")
        self.begin_button.clicked.connect(self.progress_dialog_show)

        v_layout = QVBoxLayout()
        v_layout.addWidget(self.begin_button)

        container = QWidget()
        container.setLayout(v_layout)

        self.setCentralWidget(container)

    def progress_dialog_show(self):
        self.progress = QProgressDialog()
        self.progress.setWindowFlags(self.progress.windowFlags() | Qt.WindowType.FramelessWindowHint)
        self.progress.setWindowFlag(Qt.WindowType.WindowCloseButtonHint, False)
        self.progress.setWindowTitle("请稍候")
        self.progress.setLabelText("正在处理...")
        self.progress.setMinimum(self.minimum_value)
        self.progress.setMaximum(self.maximum_value)
        self.progress.setValue(self.minimum_value)
        self.progress.setModal(True)
        self.progress.setCancelButtonText("取消执行")
        self.progress.canceled.connect(self.progress_canceled)
        self.progress.show()
        self.timer.start()

    def progress_canceled(self):
        print('用户取消了进度对话框, 当前已完成进展：{:.2f}%'.format(self.current_value / self.maximum_value * 100))
        self.progress.setValue(self.maximum_value)
        self.timer.stop()
        self.progress.accept()
        self.current_value = self.minimum_value

    def progress_dialog_update(self):
        if self.progress.value() + 1 > self.current_value:
            self.current_value = self.progress.value() + 1
        # 当进度值等于最大值时，QProgressDialog会将进度值重置为-1
        # 因此无法直接判断progress.value() >= self.maximum_value
        # 需要判断progress.value() < self.minimum_value或progress.value() >= self.progress.maximum() - 1
        if self.progress.value() < self.minimum_value or self.progress.value() >= self.progress.maximum() - 1:
            self.current_value = self.minimum_value
            self.progress.setValue(self.maximum_value)
            self.timer.stop()
            self.progress.accept()
            print('进度对话框已完成')
            return
        self.progress.setValue(self.progress.value() + 1)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyMainWindow()
    window.show()
    sys.exit(app.exec())